import csv
import pyecharts.options as opts
from pyecharts.charts import Bar


# 1)找出各省份的人口数
prov_population = {}
popu_file_path = 'human_stats/data/china_population.csv'
with open(file=popu_file_path, mode='r',encoding='gbk') as popu_file:
    # DictReader将每行信息映射到一个字典
    popu_reader = csv.DictReader(popu_file)

    # 每一行数据为一个dict
    for popu in popu_reader:
        # 取province,population两列数据
        # 删除掉省份名字中间和前后的空格
        province = popu['province'].strip().replace(' ', '')
        population = popu['population']

        # 形如：{'北京': 21893095, '湖南': 66444864}
        prov_population[province] = population

        # 读入了空数据行，{'':''}，需要删除
        if province == '':
            # 使用pop()删除字典
            prov_population.pop('')
            # 或者，del删除字典
            # del prov_population['']
            continue

        # 人口数转为int
        prov_population[province] = int(population)


# 2)按人口数从大到小排序
# {province:population,} -> [(population,province),]
top_population = []
# 字典的遍历
# 把字典item的value和key顺序对调
for k, v in prov_population.items():
    # 元组tuple对
    top_population.append((v, k))

# 按每个数据项的第一个值-value降序排序
top_population.sort(reverse=True)

# 列表切片，top 10的省份
top_population = top_population[0:10]

# 推导式：将元组列表转成字典
# [(population,province),] -> {province:population,}
top_ten_popu = {k: v for v, k in top_population}


# 3)创建排序的柱状图/条形图Bar
# 为了条形图逆序排列，x轴和y轴转置的话，需要将数据升序
x_data = list(top_ten_popu.keys())
x_data.reverse()
# 人口数从小到大排序
y_data = list(top_ten_popu.values())
y_data.sort()


low, high = min(y_data), max(y_data)

# 创建柱状图/条形图Bar
# 使用本地静态资源文件，不需要联网即可运行
bar = Bar(init_opts=opts.InitOpts(js_host='../static_resource/'))

# X轴数据项
bar.add_xaxis(xaxis_data=x_data)

# y轴数据项
bar.add_yaxis(
    series_name='人口',
    y_axis=y_data
)

# x轴数据和y轴数据对调
bar.reversal_axis()

# 全局配置
bar.set_global_opts(
    title_opts=opts.TitleOpts(
        title="全国人口数前十省份",
        subtitle='数据来源：第七次全国人口普查(2020)'
    ),
    visualmap_opts=opts.VisualMapOpts(
        orient='horizontal',
        pos_left="center",
        min_=low,
        max_=high,
        dimension=0,
        range_text=["High", "Low"],
        range_color=["#D7DA8B", "#E15457"]
    )
)
# 系列配置
bar.set_series_opts(label_opts=opts.LabelOpts(position="right"))

bar.render('human_stats/output/top_ten_province.html')
